/* INSERT NAME AND PENNKEY HERE */

`timescale 1ns / 1ns

// quotient = dividend / divisor

module divider_unsigned (
    input  wire [31:0] i_dividend,
    input  wire [31:0] i_divisor,
    output wire [31:0] o_remainder,
    output wire [31:0] o_quotient
);

    // TODO: your code here

    wire [31:0] i_remainder_temp ;
    wire [31:0] i_dividend_temp ;
    wire [31:0] i_quotient_temp ;

    wire [31:0] o_remainder_temp [31:0];
    wire [31:0] o_dividend_temp [31:0];
    wire [31:0] o_quotient_temp [31:0];


    assign i_remainder_temp  = 32'b0;
    assign i_dividend_temp   = i_dividend;
    assign i_quotient_temp   = 32'b0;

    genvar i;
    for(i=0; i<32; i=i+1) begin: divu
        if(i == 0) begin : divu_0
            divu_1iter divu_1iter_inst (
                .i_dividend(i_dividend_temp),
                .i_divisor(i_divisor),
                .i_remainder(i_remainder_temp),
                .i_quotient(i_quotient_temp),
                .o_dividend(o_dividend_temp[i]),
                .o_remainder(o_remainder_temp[i]),
                .o_quotient(o_quotient_temp[i])
            );
        end else begin : divu_others
            divu_1iter divu_1iter_inst (
                .i_dividend(o_dividend_temp[i-1]),
                .i_divisor(i_divisor),
                .i_remainder(o_remainder_temp[i-1]),
                .i_quotient(o_quotient_temp[i-1]),
                .o_dividend(o_dividend_temp[i]),
                .o_remainder(o_remainder_temp[i]),
                .o_quotient(o_quotient_temp[i])
            );
        end
    end

    assign o_remainder = o_remainder_temp[31];
    assign o_quotient  = o_quotient_temp[31];

endmodule


module divu_1iter (
    input  wire [31:0] i_dividend,
    input  wire [31:0] i_divisor,
    input  wire [31:0] i_remainder,
    input  wire [31:0] i_quotient,
    output wire [31:0] o_dividend,
    output wire [31:0] o_remainder,
    output wire [31:0] o_quotient
);
  /*
    for (int i = 0; i < 32; i++) {
        remainder = (remainder << 1) | ((dividend >> 31) & 0x1);
        if (remainder < divisor) {
            quotient = (quotient << 1);
        } else {
            quotient = (quotient << 1) | 0x1;
            remainder = remainder - divisor;
        }
        dividend = dividend << 1;
    }
    */

    // TODO: your code here

    wire [31:0] i_remainder_temp1;
    wire    remainder_cmp;

    assign i_remainder_temp1 = (i_remainder << 1) | ((i_dividend >> 31) & 32'h01);

    assign remainder_cmp = (i_remainder_temp1 < i_divisor) ? 1'b1 : 1'b0;

    assign o_remainder = (remainder_cmp == 1'b1) ? i_remainder_temp1 : (i_remainder_temp1 - i_divisor);

    assign o_quotient  = (remainder_cmp == 1'b1) ? (i_quotient << 1) : ((i_quotient << 1) | 32'b1);

    assign o_dividend  = i_dividend << 1;



endmodule
